package com.lu.utils;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * jwt token 工具类
 *
 * @author huangyao
 * @date 2022/5/7
 */
public class JwtUtils {

  /** jwt key */
  private static final String KEY = "HAPPYFIRST";

  /** 有效期 3天 */
  private static final Long VALID_TTL = 72 * 3600000L;

  /**
   * 生成jwt token
   *
   * @param username 账号
   * @return token
   */
  public static String generateToken(Long userId, String username, Long expiredTime) {
    Key key = Keys.hmacShaKeyFor(("HXFL_ADMIN_ACCESS_TOKEN_KEY_" + username).getBytes(StandardCharsets.UTF_8));
    Map<String, Object> header = new HashMap<>();
    header.put(JwsHeader.KEY_ID, username);
    Map<String, Object> claims = new HashMap<>();
    claims.put("userId", userId);
    claims.put("username", username);
    String accessToken = Jwts.builder()
        .setClaims(claims)
        .setHeader(header)
        .setExpiration(DateUtil.offset(new Date(), DateField.SECOND, expiredTime.intValue()))
        .signWith(key)
        .compressWith(CompressionCodecs.DEFLATE)
        .compact();
    return accessToken;
  }

  /**
   * 验证token
   *
   * @param token 待验证token
   * @return claims
   */
  public static Claims verifyToken(String token) {
    Claims claims = Jwts.parserBuilder()
        .setAllowedClockSkewSeconds(5 * 60) //5分钟失效过度
        .setSigningKeyResolver(new SigningKeyResolver() {
          @Override
          public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims) {
            String keyId = jwsHeader.getKeyId();
            Key key = Keys.hmacShaKeyFor(("HXFL_ADMIN_ACCESS_TOKEN_KEY_" + keyId).getBytes(StandardCharsets.UTF_8));
            return key;
          }

          @Override
          public Key resolveSigningKey(JwsHeader jwsHeader, String s) {
            return null;
          }
        })
        .build().parseClaimsJws(token).getBody();
    return claims;
  }

}
